something(6) \\ array(2, 4)
אני מחזיר שגיאה כמספר שהוא חזקה של 2.
0 - אין שגיאה.
1 - שגיאה a.
2 - שגיאה b.
4 - שגיאה c.
8 - שגיאה d.
אם לדוגמה התרחשו גם שגיאה b וגם שגיאה c אני מחזיר 6 (שזה 2 + 4, הסכום של השגיאות).
לחבר את שהגיאות ולהחזיר זו לא הבעיה.
אני מחפש דרך יעילה להפריד את השגיאות, אם לדוגמה זה 6, אז לקבל 2 ו-4. אם זה 11, לקבל 1, 2 ו-8.
אני יכול להשתמש בלולאה אבל חיפשתי אולי משהו יותר מובנה בשפה, כמו איזו פונקציה או אולי שילוב של כמה אופרטורים בינאריים כדי לקבל את התוצאה.
תודה מראש.
13 תשובות
כמובן שכל זה בהנחה ששגיאה לא יכולה להתרחש יותר מפעם אחת, אחרת זה לא אפשרי מבחינה מתמטית.
למי שלא הבין, הנה פונקציה שכתבתי שמבצעת את זה:
$elements = array();
for ($i = strlen($n = (string)base_convert($n, 10, 2)) - 1, $j = 0; $i >= 0; $i--, $j++) {
if ($n[$i]) {
$elements[] = (int)base_convert(pow(10, $j), 2, 10);
}
}
return $elements;
}
הפלט של זה:
הוא זה:
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(8)
}
array(2) {
[0]=>
int(2)
[1]=>
int(4)
}
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(16)
}
אפשר לראות שזה מוצא את הגורמים שהם חזקות של 2. השאלה היא האם יש משהו מובנה בשפה שיעבוד מהר יותר.
יעזור יותר להבין אם תסביר שוב ובמילים אחרות מה צריך לקבל, כמה דוגמאות לפלט קלט ומה לא עובד בקוד שלך
מאוד יכול להיות שאתה לא צריך להפריד שום דבר בכלל וסתם כמה תנאים יספיקו לך:
const A = 1;
const B = 2;
const C = 4;
const D = 8;
$someValue = 12;
if( $someValue & A) echo 'its a A', '<br/>';
if( $someValue & B) echo 'its a B', '<br/>';
if( $someValue & C) echo 'its a C', '<br/>';
if( $someValue & D) echo 'its a D', '<br/>';
נתתי שלוש דוגמאות לפלט ולקלט, בהודעה השניה שלי.
הקוד שלי עובד, אני פשוט רוצה לדעת האם קיים משהו זהה מובנה בשפה.
בנוגע לתגובה השנייה שלך, זה טוב אם אני רוצה לדעת האם שגיאה מסוימת קרתה.
מה שאני רוצה זה "לחלץ" את השגיאות שהתרחשו.
תכניס את התנאים מהתגובה השניה שלי לתוך לולאה שבה תבדוק את כל השגיאות האפשריות האם הם התרחשו
אני לא תמיד יודע מהן כל השגיאות האפשריות.
במסד מוצמדת כל שגיאה (במילים) אל המספר שלה.
ככה שלחלץ את השגיאות זו הדרך היחידה, השאלה היא האם יש דרך לחלץ את השגיאות בצורה טובה יותר.
חוץ מלעבור בלולאה על כל החזקות של שתיים? לא חושב.
למה אתה בכלל מחבר אותם ביחד? למה שהפונקציה שלך לא תחזיר מערך של מספרי שגיאות ולא את הביטים שלהן ?
לא צריך לעבור עם לולאה על כל החזקות של 2, זה סתם בזבוז. תראה את הקוד שלי.
ואני באמת אחזיר מערך. סתם מיותר להתעסק עם זה כשלא צריך.
בדיוק אותה לולאה, רק שבמקום מספרים אתה עובר על מחרוזות, שזה רעיון קצת יותר גרוע.. מבחינת כמות מעברי הלולאה הם זהים, מבחינת הפעולות שצריך לעשות בתוך הלולאה - המעברים למחרוזת והשוואת מחרוזות נראים לי קצת מיותרים.
אני לא עובד על כל החזקות של 2.
אני רץ על הספרות של המספר.
לדוגמה 11 שמיוצג בבסיס בינארי על ידי 1011.
מתחיל מספרת האחדות, היא 1? כן. j כרגע הוא 0. 10 בחזקת 0 זה 1, נמיר לעשרוני מבינארי, נשאר 1, מוסיפים למערך.
ספרת העשרות - 1. j הוא 1 כרגע. 10 בחזקת 1 זה 10, נמיר מבינארי לעשרוני, נקבל 2. מוסיפים 2 למערך.
ספרת המאות - 0. j הוא כרגע 2.
ספרת האלפים - 1. j הוא כרגע 3. 10 בחזקת 3 זה 1000, נמיר לעשרוני, נקבל 8. נוסיף למערך 8.
ככה קיבלנו 1, 2, 8. פשוט רצים על הספרות, בודקים מה "דלוק" (1), ממירים אותו לעשרוני ומוסיפים למערך.
ככה שהלולאה רצה n פעמים, כש-n זה מספר הספרות של הקלט.
הבנתי את הקוד שלך :)
במקרה הגרוע - בדיוק אותו n תהיה כמות הפעמים שיהיה עליך להכפיל משהו ב 2 כדי לקבל את החזקה הבאה שלה.
{
$result = [];
$pow = 0.5;
while( $n >= ( $pow *= 2 ) )
if($n & $pow)
$result[] = $pow;
return $result;
}
print_r(elements(517));
הייתי בטוח שריצה על החזקות של 2 יהיה פחות מהיר -.-
שלך מהיר יותר (פי 7-8) וגם עובד במספרים גדולים (שלי לא בגלל base_convert).
;)